5
תגובות
חריגת זיכרון
פתח
iiddaannyy
,
יש לי את המחלקה הבאה שצובעת סינטקס:
היא לקוחה ברובה מהאתר php.net.
המחלקה עובדת בצורה הבאה.
1. לולאה על כל תווי הקלט.
1.1. אם זה תו פתיחה של הערה, של תג html או של קוד php, אז:
1.1.1. מפעילים את המתודה המתאימה של המחלקה (php, הערה או תג).
1.1.1.1. בתוך המתודה הזו ממשיכים לרוץ עם לולאה על הקלט (מאיפה שהגענו בלולאה בשורה 1) עד שמגיעים לתג הסגירה:
1.1.1.1.1. מוסיפים את התו הנוכחי אל המשתנה buffer.
1.1.1.2. אחרי סיום פעולת הלולאה המשתנה buffer מכיל את מה שחיפשנו במתודה (קוד php או הערה וכו').
(מכאן אתייחס רק לחלק של מתודת ה-php)
1.1.1.3. עם highlight_string צובעים את הקוד שיש ב-buffer ומכניסים לתוך buffer.
1.1.1.4. משרשרים אל משתנה המחלקה codeHighlighted את buffer
1.2. אחרת (אם זה לא תו פתיחה של הערה, של תג html או של קוד php), אז:
1.2.1. זה סתם סטרינג אז מוסיפים אותו למשתנה המחלקה codeHightlighted.
2. מחזירים כפלט את codeHighlighted.
עד כאן לאופן הפעולה של המחלקה.
הבעיה שלי היא:
בשורה:
אם אני שולח html למחלקה אני מקבל חזרה את הקוד צבוע כמו שצריך והכל טוב.
אבל אם אני שולח php (או php+html) נוצרת החריגה.
מה גורם לחריגה הזו?
האם זה אופן הפעולה של המחלקה (ריצה על כל התווים של הקלט) שגורם לחריגה ב-ram?
האם זו הפונקציה highlight_string? (היא עובדת אם אני מפעיל אותה באופן חיצוני מחוץ למחלקה)
מה זה יכול להיות?
תודה מראש.
<?php
class code_highlight {
private $pointer = 0,
$code = '',
$codeHighlighted = '';
public function setCode($code = '') {
$code = trim($code);
$code = str_replace("\t", ' ', $code);
$this->code = $code;
$this->codeHighlighted = '';
}
private function htmlComment_highlight($position) {
$buffer = '<span-style="color:-green;font-style:italic;"><';
for($position++; $position < strlen($this->code) && $this->code[$position] != '>'; $position++) {
$buffer .= $this->code[$position];
}
$buffer .= "></span>";
$this->codeHighlighted .= $buffer;
return $position;
}
private function htmlTag_highlight($position) {
$buffer = '<<span-style="color:-purple;">';
$coloredTagName = false;
for($position++; $position < strlen($this->code) && $this->code[$position] != '>'; $position++) {
if($this->code[$position] == ' ' && !$coloredTagName) {
$coloredTagName = true;
$buffer.='</span>';
}
elseif($this->code[$position] != ' ' && $coloredTagName) {
$attribute = '';
for(; $position < strlen($this->code) && $this->code[$position] != '>'; $position++) {
if($this->code[$position] != '=') {
$attribute .= $this->code[$position];
}
else {
$value= '';
$buffer .= "<span-style=\"color:-red;\">$attribute</span>=";
$attribute = '';
$inQuote = false;
$QuoteType = null;
for($position++; $position < strlen($this->code) && $this->code[$position] != '>' && $this->code[$position] != ' '; $position++) {
if($this->code[$position] == '"' || $this->code[$position] == '\''){
$inQuote = true;
$QuoteType = $this->code[$position];
$value.=$QuoteType;
for($position++; $position < strlen($this->code) && $this->code[$position] != '>' && $this->code[$position] != $QuoteType; $position++) {
$value .= $this->code[$position];
}
$value.=$QuoteType;
}
else {
$value .= $this->code[$position];
}
}
$buffer .= "<span-style=\"color:-blue;\">$value</span>";
break;
}
}
if($attribute != '') {
$buffer.= "<span-style=\"color:-red;\">$attribute</span>";
}
}
if($this->code[$position] == '>' ){
break;
}
$buffer.= $this->code[$position];
}
if($this->code[$position] == '>' && !$coloredTagName){
$buffer.='</span>>';
$position++;
}
$this->codeHighlighted .= $buffer;
return --$position;
}
private function php_highlight($position) {
$buffer = '';
$inQuotes = false;
$quotesType = false;
for(; $position < strlen($this->code) &&($position > 1 && ($this->code[$position-2] != '?' || $this->code[$position-1] != '>' || $inQuotes)); $position++) {
if ($this->code[$position] == '"' || $this->code[$position] == '\'') {
if ($inQuotes) {
if ($quotesType == $this->code[$position]) {
$quotesType = false;
$inQuotes = false;
}
}
else {
$quotesType = $this->code[$position];
$inQuotes = true;
}
}
$buffer .= $this->code[$position];
}
$buffer = highlight_string($buffer, true);
$buffer = str_replace('<code><span style="color: #000000">'."\n", '<span style="color: #000000">', $buffer);
$buffer = str_replace("\n</span>\n</code>", '</span>', $buffer);
$buffer = str_replace('<br />', '', $buffer);
$buffer = str_replace('<span style="color: ', '<span-style="color:-', $buffer);
$this->codeHighlighted .= $buffer;
return --$position;
}
public function highlight() {
$this->codeHighlighted = '';
for($pointer = 0; $pointer < mb_strlen($this->code); $pointer++) {
$thisChar = $this->code[$pointer];
$nextChar = ($pointer+1 == mb_strlen($this->code)) ? '' : $this->code[$pointer+1];
if($thisChar == '<') {
if($nextChar == '!') {
$pointer = $this->htmlComment_highlight($pointer);
}
elseif ($nextChar == '?') {
$pointer = $this->php_highlight($pointer);
}
else {
$pointer = $this->htmlTag_highlight($pointer);
}
}
else {
$this->codeHighlighted .= $this->code[$pointer];
}
}
$this->codeHighlighted = str_replace(' ', ' ', $this->codeHighlighted);
$this->codeHighlighted = str_replace('<br-/>', '<br />', $this->codeHighlighted);
$this->codeHighlighted = str_replace('<span-style="color:-', '<span style="color: ', $this->codeHighlighted);
return nl2br("<span style=\"font-family: monospace; font-size: 13px;\">$this->codeHighlighted</span>");
}
}
?>
class code_highlight {
private $pointer = 0,
$code = '',
$codeHighlighted = '';
public function setCode($code = '') {
$code = trim($code);
$code = str_replace("\t", ' ', $code);
$this->code = $code;
$this->codeHighlighted = '';
}
private function htmlComment_highlight($position) {
$buffer = '<span-style="color:-green;font-style:italic;"><';
for($position++; $position < strlen($this->code) && $this->code[$position] != '>'; $position++) {
$buffer .= $this->code[$position];
}
$buffer .= "></span>";
$this->codeHighlighted .= $buffer;
return $position;
}
private function htmlTag_highlight($position) {
$buffer = '<<span-style="color:-purple;">';
$coloredTagName = false;
for($position++; $position < strlen($this->code) && $this->code[$position] != '>'; $position++) {
if($this->code[$position] == ' ' && !$coloredTagName) {
$coloredTagName = true;
$buffer.='</span>';
}
elseif($this->code[$position] != ' ' && $coloredTagName) {
$attribute = '';
for(; $position < strlen($this->code) && $this->code[$position] != '>'; $position++) {
if($this->code[$position] != '=') {
$attribute .= $this->code[$position];
}
else {
$value= '';
$buffer .= "<span-style=\"color:-red;\">$attribute</span>=";
$attribute = '';
$inQuote = false;
$QuoteType = null;
for($position++; $position < strlen($this->code) && $this->code[$position] != '>' && $this->code[$position] != ' '; $position++) {
if($this->code[$position] == '"' || $this->code[$position] == '\''){
$inQuote = true;
$QuoteType = $this->code[$position];
$value.=$QuoteType;
for($position++; $position < strlen($this->code) && $this->code[$position] != '>' && $this->code[$position] != $QuoteType; $position++) {
$value .= $this->code[$position];
}
$value.=$QuoteType;
}
else {
$value .= $this->code[$position];
}
}
$buffer .= "<span-style=\"color:-blue;\">$value</span>";
break;
}
}
if($attribute != '') {
$buffer.= "<span-style=\"color:-red;\">$attribute</span>";
}
}
if($this->code[$position] == '>' ){
break;
}
$buffer.= $this->code[$position];
}
if($this->code[$position] == '>' && !$coloredTagName){
$buffer.='</span>>';
$position++;
}
$this->codeHighlighted .= $buffer;
return --$position;
}
private function php_highlight($position) {
$buffer = '';
$inQuotes = false;
$quotesType = false;
for(; $position < strlen($this->code) &&($position > 1 && ($this->code[$position-2] != '?' || $this->code[$position-1] != '>' || $inQuotes)); $position++) {
if ($this->code[$position] == '"' || $this->code[$position] == '\'') {
if ($inQuotes) {
if ($quotesType == $this->code[$position]) {
$quotesType = false;
$inQuotes = false;
}
}
else {
$quotesType = $this->code[$position];
$inQuotes = true;
}
}
$buffer .= $this->code[$position];
}
$buffer = highlight_string($buffer, true);
$buffer = str_replace('<code><span style="color: #000000">'."\n", '<span style="color: #000000">', $buffer);
$buffer = str_replace("\n</span>\n</code>", '</span>', $buffer);
$buffer = str_replace('<br />', '', $buffer);
$buffer = str_replace('<span style="color: ', '<span-style="color:-', $buffer);
$this->codeHighlighted .= $buffer;
return --$position;
}
public function highlight() {
$this->codeHighlighted = '';
for($pointer = 0; $pointer < mb_strlen($this->code); $pointer++) {
$thisChar = $this->code[$pointer];
$nextChar = ($pointer+1 == mb_strlen($this->code)) ? '' : $this->code[$pointer+1];
if($thisChar == '<') {
if($nextChar == '!') {
$pointer = $this->htmlComment_highlight($pointer);
}
elseif ($nextChar == '?') {
$pointer = $this->php_highlight($pointer);
}
else {
$pointer = $this->htmlTag_highlight($pointer);
}
}
else {
$this->codeHighlighted .= $this->code[$pointer];
}
}
$this->codeHighlighted = str_replace(' ', ' ', $this->codeHighlighted);
$this->codeHighlighted = str_replace('<br-/>', '<br />', $this->codeHighlighted);
$this->codeHighlighted = str_replace('<span-style="color:-', '<span style="color: ', $this->codeHighlighted);
return nl2br("<span style=\"font-family: monospace; font-size: 13px;\">$this->codeHighlighted</span>");
}
}
?>
היא לקוחה ברובה מהאתר php.net.
המחלקה עובדת בצורה הבאה.
1. לולאה על כל תווי הקלט.
1.1. אם זה תו פתיחה של הערה, של תג html או של קוד php, אז:
1.1.1. מפעילים את המתודה המתאימה של המחלקה (php, הערה או תג).
1.1.1.1. בתוך המתודה הזו ממשיכים לרוץ עם לולאה על הקלט (מאיפה שהגענו בלולאה בשורה 1) עד שמגיעים לתג הסגירה:
1.1.1.1.1. מוסיפים את התו הנוכחי אל המשתנה buffer.
1.1.1.2. אחרי סיום פעולת הלולאה המשתנה buffer מכיל את מה שחיפשנו במתודה (קוד php או הערה וכו').
(מכאן אתייחס רק לחלק של מתודת ה-php)
1.1.1.3. עם highlight_string צובעים את הקוד שיש ב-buffer ומכניסים לתוך buffer.
1.1.1.4. משרשרים אל משתנה המחלקה codeHighlighted את buffer
1.2. אחרת (אם זה לא תו פתיחה של הערה, של תג html או של קוד php), אז:
1.2.1. זה סתם סטרינג אז מוסיפים אותו למשתנה המחלקה codeHightlighted.
2. מחזירים כפלט את codeHighlighted.
עד כאן לאופן הפעולה של המחלקה.
הבעיה שלי היא:
Allowed memory size of 67108864 bytes exhausted (tried to allocate 66322389 bytes)
בשורה:
$this->codeHighlighted .= $buffer;
אם אני שולח html למחלקה אני מקבל חזרה את הקוד צבוע כמו שצריך והכל טוב.
אבל אם אני שולח php (או php+html) נוצרת החריגה.
מה גורם לחריגה הזו?
האם זה אופן הפעולה של המחלקה (ריצה על כל התווים של הקלט) שגורם לחריגה ב-ram?
האם זו הפונקציה highlight_string? (היא עובדת אם אני מפעיל אותה באופן חיצוני מחוץ למחלקה)
מה זה יכול להיות?
תודה מראש.
5 תשובות
ענה
iiddaannyy
ב
31 לדצמבר 2011
#
הבעיה בשורה 101 בתוך המתודה php_highlight.
הבעיה שלך ב-php_highlight בלולאה:
for(; $position < strlen($this->code) &&...
ובלי לעליב, המחלקה בנויה לא טוב, ולא בצורה יעילה. את ה-highlighting עושים אחרת. אבל שיהיה.
החריגה נובעת מזה שיש יותר מדי נתונים ששמורים בכל מיני משתנים (בזכרון), יותר ממה שמותר לסקריפט לשמור. כמו ש ctulhu אמר, למה שלא תמשתמש במחקה קיימת? למשל geshi. אני משתמש בה.
בכל אופן, אם אתה רוצה לכתוב כזו בעצמך - לפרק קוד לחלקים עדיף עם tokenizing ולא לפי תווים.
ענה
iiddaannyy
ב
01 לינואר 2012
#
המחלקה לא שלי, לקחתי אותה מאיזו תגובה ב-php.net.
בכל אופן תודה, אני עובד על מחלקה חדשה. :)
ענה
iiddaannyy
ב
01 לינואר 2012
#
בניתי מחלקה חדשה.. :)
אני אפתח על זה מדריך כדי שכולם יוכלו להשתמש בה. (: